package com.qzsoft.zhjd.asphalt.modules.asphaltdata.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qzsoft.zhjd.asphalt.modules.asphaltdata.dto.*;
import com.qzsoft.zhjd.asphalt.modules.asphaltdata.entity.AsphaltDataEntity;
import com.qzsoft.zhjd.asphalt.modules.asphaltdata.entity.NGuobangData;
import com.qzsoft.zhjd.asphalt.modules.asphaltdata.mapper.AsphaltDataMapper;
import com.qzsoft.zhjd.asphalt.modules.asphaltdata.service.AsphaltDataService;
import com.qzsoft.zhjd.asphalt.modules.asphaltdatasieve.dto.AsphaltDataSievingAvgDto;
import com.qzsoft.zhjd.asphalt.modules.asphaltdatasieve.entity.AsphaltDataSieveEntity;
import com.qzsoft.zhjd.asphalt.modules.asphaltdatasieve.service.AsphaltDataSieveService;
import com.qzsoft.zhjd.asphalt.modules.asphaltdataweight.entity.AsphaltDataWeightEntity;
import com.qzsoft.zhjd.asphalt.modules.asphaltdataweight.service.AsphaltDataWeightService;
import com.qzsoft.zhjd.asphalt.modules.asphaltmatch.entity.AsphaltMatchEntity;
import com.qzsoft.zhjd.asphalt.modules.asphaltmatch.entity.AsphaltMatchHotEntity;
import com.qzsoft.zhjd.asphalt.modules.asphaltmatch.entity.AsphaltMatchThresholdEntity;
import com.qzsoft.zhjd.asphalt.modules.asphaltmatch.mapper.AsphaltMatchMapper;
import com.qzsoft.zhjd.asphalt.modules.asphaltmatch.service.AsphaltMatchHotService;
import com.qzsoft.zhjd.asphalt.modules.asphaltmatch.service.AsphaltMatchService;
import com.qzsoft.zhjd.asphalt.modules.asphaltmatch.service.AsphaltMatchThresholdService;
import com.qzsoft.zhjd.asphalt.modules.nAsphaltDataConfig.entity.NAsphaltDataConfigEntity;
import com.qzsoft.zhjd.asphalt.modules.nAsphaltDataConfig.service.NAsphaltDataConfigService;
import com.qzsoft.zhjd.common.annotation.ZhjdDataFilter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qzsoft.system.modules.sysstation.entity.SysStationEntity;
import com.qzsoft.system.modules.sysstation.enums.SysStationType;
import com.qzsoft.system.modules.sysstation.service.SysStationService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

/**
 * @author linhuawei
 * @ClassName AsphaltDataServiceImpl
 * @Description 沥青生产数据业务实现
 * @since 2021-11-23
 */
@Slf4j
@Service
public class AsphaltDataServiceImpl extends ServiceImpl<AsphaltDataMapper, AsphaltDataEntity>
        implements AsphaltDataService {

    @Autowired
    private AsphaltMatchService asphaltMatchService;

    @Autowired
    private AsphaltMatchThresholdService asphaltMatchThresholdService;

    @Autowired
    private SysStationService sysStationService;

    @Autowired
    private AsphaltDataSieveService asphaltDataSieveService;

    @Autowired
    private AsphaltMatchHotService asphaltMatchHotService;

    @Autowired
    private AsphaltDataMapper asphaltDataMapper;

    @Autowired
    private AsphaltMatchMapper asphaltMatchMapper;


    // 获取国磅数据上传URL
    @Value("${dibang.send.url:}")
    private String txgbDataSendUrl;
    private final static String DEFAULT_URL = "https://smart.ilabx.cn/ay230050z/materials/WisdomWeighbridgeOrder/saveTXMixingPlantData";

    @ZhjdDataFilter(tableAlias = "t1")
    @Override
    public List<ProduceAsphaltDto> produceAsphalt(Map<String, Object> params) {
        return baseMapper.produceAsphalt(params);
    }

    @ZhjdDataFilter
    @Override
    public DayDataStatisticsDto dayDataStatistics(Map<String, Object> params) {
        // 获取符合条件最新一条数据
        AsphaltDataEntity temp = selectTopOne(params);
        if (null == temp) {
            return null;
        }

        // 设置查询条件
        String stationCode = temp.getStationCode();
        String matchCode = temp.getMatchCode();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String day = sdf.format(temp.getDischargeTime());
        params.put("stationCode", stationCode);
        params.put("matchCode", matchCode);
        //params.put("day", temp.getDischargeTime());
        params.put("day", day);

        QueryWrapper<SysStationEntity> unionOne = new QueryWrapper<SysStationEntity>().eq("code", stationCode);
        // 获取拌合楼信息
        SysStationEntity station = sysStationService.getOne(unionOne);

        // 获取生产配比
        AsphaltMatchEntity match = asphaltMatchService.getByCode(matchCode);

        // 如果配比存在，获取上下限设置
        AsphaltMatchThresholdEntity matchThreshold = null;
        List<AsphaltMatchHotEntity> hots = null;
        if (null != match) {
            matchThreshold = asphaltMatchThresholdService.getByMatchName(match.getMatchName());
            hots = asphaltMatchHotService.listByMatchId(match.getId());
        }
        // 获取油石比、温度、筛孔、参配比
        List<DayDataStatisticsListDto> dataList = baseMapper.dataListForDayDataStatistics(params);

        // 全局图
        List<ShellGlobalListDto> shellGlobal = baseMapper.getShellGobalList(params);
        JSONObject item = new JSONObject();
        item.put("color:", "'#409EFF'");
        JSONObject norma = new JSONObject();
        norma.put("normal:", item);
        List<JSONObject> jsonList = new ArrayList<>();
        for (int i=0,len=shellGlobal.size();i<len;i++) {
            JSONObject map = new JSONObject();
            map.put("name", "生产级配");
            map.put("type", "line");
            List<BigDecimal> list = new ArrayList<>();
            list.add(null);
            if(null == shellGlobal.get(i)) {
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
                list.add(null);
            } else {
                list.add(shellGlobal.get(i).getSieve0d075());
                list.add(shellGlobal.get(i).getSieve0d15());
                list.add(shellGlobal.get(i).getSieve0d3());
                list.add(shellGlobal.get(i).getSieve0d6());
                list.add(shellGlobal.get(i).getSieve1d18());
                list.add(shellGlobal.get(i).getSieve2d36());
                list.add(shellGlobal.get(i).getSieve4d75());
                list.add(shellGlobal.get(i).getSieve9d5());
                list.add(shellGlobal.get(i).getSieve13d2());
                list.add(shellGlobal.get(i).getSieve16());
                list.add(shellGlobal.get(i).getSieve19());
                list.add(shellGlobal.get(i).getSieve26d5());
                list.add(shellGlobal.get(i).getSieve31d5());
                list.add(shellGlobal.get(i).getSieve37d5());
                list.add(shellGlobal.get(i).getSieve53());
            }
            map.put("data", list);
            map.put("itemStyle", norma);
            jsonList.add(map);
        }

        // 获取筛孔平均值
        AsphaltDataSievingAvgDto avgSieving = asphaltDataSieveService.getSievingAvg(params);

        // 返回结果数据
        DayDataStatisticsDto dto = new DayDataStatisticsDto();
        dto.setStation(station);
        dto.setDataList(dataList);
        dto.setMatchThreshold(matchThreshold);
        dto.setDay(day);
        dto.setMatch(match);
        dto.setAvgSieving(avgSieving);
        dto.setHots(hots);

        dto.setGlobal(jsonList);
        return dto;
    }

    @ZhjdDataFilter(tableAlias = "t1")
    @Override
    public List<ReportCountDto> reportCount(Map<String, Object> params) {
        // 获取拌合楼数据
        Map<String, Object> stationParams = new HashMap<String, Object>();
        stationParams.put("type", SysStationType.ASPHALT.getValue());
        List<SysStationEntity> stationList = sysStationService.list(stationParams);

        // 获取每个拌和站数据
        List<ReportCountDto> list = new ArrayList<ReportCountDto>();
        if (ObjectUtils.isNotEmpty(stationList)) {
            ReportCountDto dto;
            List<ReportCountDetailsDto> details;
            for (SysStationEntity station : stationList) {
                params.put("stationCode", station.getCode());
                details = baseMapper.reportCount(params);
                dto = new ReportCountDto();
                dto.setStation(station);
                dto.setDetails(details);
                list.add(dto);
            }
        }
        return list;
    }

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public Long saveDataBaseUploadTxgb(JSONObject json) {
        log.info("------0---------------json:-------------------------");
        JSONObject columns = json.getJSONObject("columns");
        if(columns == null){
            return null;
        }
        // stationId 存 type
        String stationId = columns.getString("type");
        Integer indexId = json.getInteger("indexId");
        log.info("------0---------------indexId:-------------------------",indexId);
        java.util.function.Function<Object, Date> toDate = v -> {
            if(v == null){
                return null;
            }
            try {
                long ts = Long.parseLong(String.valueOf(v));
                if(String.valueOf(v).length() <= 10){
                    ts = ts * 1000;
                }
                return new Date(ts);
            } catch (Exception e){
                return null;
            }
        };
        String[] cols = new String[]{
                "liushuihao","chehao","pinming","danwei","maozhong","pizhong","jingzhong","maozhongsibang","pizhongsibang",
                "maozhongshijian","pizhongshijian","riqi","daxie","zhefangxishu","fangliang","feiyong","wancheng","zhongliang",
                "lingkoupinming","shijikouliang","lingkou","lingkou2","shizhong","danjia","bei1","feiyong2","bei2","guige",
                "zhuangtai","zuofeishijian","fahuoyuan","fuyongshijian","zhenghao","jinedaxie","xiugaishijian","erpdouble",
                "leijicheci","leijifang","leijizhong","leijijine","yuanfa","sunhao","yucunliushui","bei3","bei4","bei5",
                "pizhongyichang","yichangxinxi","diqu","quhao","gongsi","zidingliushui","leixing","bei6","bei7","shangchuan",
                "jiesuan","jiesuanriqi","jiesuanbeizhu","shangchuanshijian","jinxiaoliushui","shuifenkouzhong","yunfeidanjia",
                "yingjieyunfei","yunfeijine","kouyunfei","kouhuokuan","yunfeidaxie","shijiliushui","fujian1","fujian2","fujian3",
                "fujian4","fujian5","fujian6","fajian1","fajian2","fajian3","fajian4","beiyongjine","tebieshu1","tebieshu2",
                "tebiewenzi","baoguanyijian","bianhao","fuhe","cangguan","yifuhe","liuliang","liusunhao","beiyong1","beiyong2",
                "zhuangxiefei","guoqiaofei","jiayoufei","xiuchefei","qitafei","tiaoma","kahao","jiesuanliushui","piciliushui",
                "danjia2","jine2","danjia3","jine3","kou3","kou4","ankou","jiesuan1","jiesuan2","weijiesuan","pingmingID",
                "danweiID","guigeID","bei1ID","bei2ID","bei3ID","bei4ID","bei5ID","bei6ID","bei7ID","gongchengID","laiyuanID",
                "xiangmuID","fasongzhuangtai","cuowuxinxi","zhandianID","zhandianming","dibanghao","shengchanshebeiID",
                "shengchanshebeiname","zuizhongshuliang","beiyongshuzi","yajin","yituiyajin","yajinbiaoji","yajinbeizhu",
                "tuiyajintime","stationId","indexId"
        };
        java.util.Set<String> dateCols = new java.util.HashSet<>(java.util.Arrays.asList(
                "maozhongshijian","pizhongshijian","riqi","zuofeishijian","fuyongshijian","xiugaishijian","jiesuanriqi","shangchuanshijian","tuiyajintime"
        ));

        java.util.List<Object> values = new java.util.ArrayList<>(cols.length);
        for(String c : cols){
            Object v;
            if("stationId".equals(c)){
                v = stationId;
            } else if("indexId".equals(c)){
                v = indexId;
            } else if(dateCols.contains(c)){
                v = toDate.apply(columns.get(c));
            } else {
                v = columns.get(c);
            }
            values.add(v);
        }
        String placeholders = String.join(",", java.util.Collections.nCopies(cols.length, "?"));
        String sql = "INSERT INTO n_guobang_data (" + String.join(", ", cols) + ") VALUES (" + placeholders + ")";
        jdbcTemplate.update(sql, values.toArray());
//        //将数据传给第三方
//        txgbDataSendUrl = StrUtil.isNotBlank(txgbDataSendUrl) ? txgbDataSendUrl : DEFAULT_URL;
////            异步发送
//        CompletableFuture.supplyAsync(() -> {
//            try {
//                return restTemplate.postForEntity(txgbDataSendUrl, columns, String.class);
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        }).thenAccept(response -> {
//            // 处理响应
//            System.out.println(new Date());
//            System.out.println("=======================");
//            System.out.println("Response: " + response.getBody());
//            //如果发送成功，更新发送状态send 为1；
//            if (response.getStatusCodeValue() == 200) {
//                String sql1 = "update n_guobang_data set send = 1 where indexid = " + indexId;
//                jdbcTemplate.update(sql1);
//            }
//        }).exceptionally(throwable -> {
//            // 异常处理
//            System.err.println("Error: " + throwable.getMessage());
//            return null;
//        });

        return columns.getLong("INDEX_ID");
    }

    /**
     * 发送旧数据；
     * 每天的0点、6点、12点、18点执行；
     * //间隔1分钟执行一次；
     */

//    @Scheduled(fixedRate = 60000)
    @Scheduled(cron = "0 0 0,6,12,18 * * ?")
    public void sendOldData() {
        try {
            // 确保URL已正确设置
            String url = StrUtil.isNotBlank(txgbDataSendUrl) ? txgbDataSendUrl : DEFAULT_URL;

            // 查询未发送的数据，限制每次处理10条
            List<NGuobangData> dataList = jdbcTemplate.query(
                    "SELECT * FROM n_guobang_data WHERE send = 0 and stationId ='TXGB2B01'  ORDER BY indexid LIMIT 50",
                    new BeanPropertyRowMapper<>(NGuobangData.class)
            );

            if (CollUtil.isNotEmpty(dataList)) {
                log.info("开始发送{}条未发送的国磅数据", dataList.size());
                int count = 0;
                // 发送数据
                for (NGuobangData data : dataList) {
                    try {
                        ResponseEntity<String> res = restTemplate.postForEntity(url, data, String.class);
                        int statusCodeValue = res.getStatusCodeValue();

                        // 如果发送成功，更新发送状态
                        if (statusCodeValue == 200) {
                            String sql1 = "UPDATE n_guobang_data SET send = 1 WHERE indexid = ?";
                            jdbcTemplate.update(sql1, data.getIndexid());
                            log.info("国磅数据indexid={}发送成功", data.getIndexid());
                        } else {
                            log.warn("国磅数据indexid={}发送失败，状态码: {}", data.getIndexid(), statusCodeValue);
                        }
                    } catch (Exception e) {
                        log.error("发送国磅数据indexid={}时发生异常", data.getIndexid(), e);
                        count++;
                        //如果超过5次发送不成功，则跳出本次执行任务。下次任务再次尝试。避免造成一直重复调用，浪费服务器性能。
                        if (count > 5) {
                            return;
                        }
                    }
                }
                sendOldData();
            } else {
                log.debug("没有需要发送的国磅数据");
            }
        } catch (Exception e) {
            log.error("执行发送旧数据任务时发生异常", e);
        }


//        // 或者使用query方法配合RowMapper
//        List<NGuobangData> dataList = jdbcTemplate.query(
//                "SELECT * FROM n_guobang_data WHERE  send = 0 limit 10",
//                new BeanPropertyRowMapper<>(NGuobangData.class)
//        );
//        if(CollUtil.isNotEmpty(dataList)){
//            //发送数据；
//            for(NGuobangData data :dataList ){
//                ResponseEntity<String> res = restTemplate.postForEntity(txgbDataSendUrl, data, String.class);
//                int statusCodeValue = res.getStatusCodeValue();
//                if (statusCodeValue == 200) {
//                    String sql1 = "update n_guobang_data set send = 1 where indexid = " + data.getIndexid();
//                    jdbcTemplate.update(sql1);
//                }
//            }
//            sendOldData();
//        }

    }

    @Override
    public AsphaltDataDetailsDto details(String id) {
        // 获取数据
        AsphaltDataEntity data = baseMapper.selectById(id);
        if (null == data) {
            return null;
        }

        // 获取筛孔数据
        AsphaltDataSieveEntity sieveData = asphaltDataSieveService.getById(id);

        // 获取拌和站信息
        String stationId = data.getStationCode();
        SysStationEntity station = sysStationService.getOne(new QueryWrapper<SysStationEntity>().eq("code", stationId));

        // 获取配比信息
        String matchCode = data.getMatchCode();
        AsphaltMatchEntity match = asphaltMatchService.getByCode(matchCode);
        AsphaltMatchThresholdEntity threshold = null;
        if (null != match) {
            String matchName = match.getMatchName();
            threshold = asphaltMatchThresholdService.getByMatchName(matchName);
        }

        // 返回数据
        AsphaltDataDetailsDto dto = new AsphaltDataDetailsDto();
        dto.setData(data);
        dto.setThreshold(threshold);
        dto.setStation(station);
        dto.setMatch(match);
        dto.setSieveData(sieveData);
        return dto;
    }

    @Override
    public AsphaltDataEntity selectTopOne(Map<String, Object> params) {
        // 根据查询条件判断是否又符合条件的数据
        if (ObjectUtils.isEmpty(params.get("stationCode"))) {
            params.put("stationCode", null);
        }
        if (ObjectUtils.isEmpty(params.get("matchCode"))) {
            params.put("matchCode", null);
        }
        if (ObjectUtils.isEmpty(params.get("matchType"))) {
            params.put("matchType", null);
        }
        if (ObjectUtils.isEmpty(params.get("matchName"))) {
            params.put("matchName", null);
        }
        if (ObjectUtils.isEmpty(params.get("day"))) {
            params.put("day", null);
        }
        return baseMapper.selectTopOne(params);
    }

    /**
     * 获取所有有数据得时间
     *
     * @return
     */
    @Override
    public List<String> requestTime(Map<String, Object> params) {
        return asphaltDataMapper.requestTime(params);
    }

    /**
     * 根据级配类型获取生产配比
     *
     * @param type
     * @return
     */
    @Override
    public List<Map<String, Object>> getMatchCode(String type) {
        List<AsphaltMatchEntity> matchEntities = asphaltMatchMapper.selectList(new QueryWrapper<AsphaltMatchEntity>().eq("match_type", type));
        List<Map<String, Object>> data = new ArrayList<>();
        matchEntities.forEach(val -> {
            Map<String, Object> map = new HashMap<>();
            map.put("value", val.getMatchCode());
            map.put("label", val.getMatchCode());
            data.add(map);
        });
        return data;
    }

    @Override
    public List<Map<String, Object>> getInitMatchCode() {
        List<AsphaltMatchEntity> matchEntities = asphaltMatchMapper.selectList(new QueryWrapper<AsphaltMatchEntity>().orderByAsc("id"));
        List<Map<String, Object>> data = new ArrayList<>();
        matchEntities.forEach(val -> {
            Map<String, Object> map = new HashMap<>();
            map.put("value", val.getMatchCode());
            map.put("label", val.getMatchCode());
            data.add(map);
        });
        return data;
    }

    @Override
    @ZhjdDataFilter
    public AsphaltDataEntity getLatestData(Map<String, Object> params) {
        QueryWrapper<AsphaltDataEntity> queryWrapper = new QueryWrapper<AsphaltDataEntity>();
        if(ObjectUtils.isNotEmpty(params.get("baseCode"))) {
            queryWrapper.eq("base_code", params.get("baseCode").toString());
        }
        if(ObjectUtils.isNotEmpty(params.get("stationCode"))) {
            queryWrapper.eq("station_code", params.get("stationCode").toString());
        }
        if(ObjectUtils.isNotEmpty(params.get("matchType"))) {
            queryWrapper.eq("match_type", params.get("matchType").toString());
        }
        if(ObjectUtils.isNotEmpty(params.get("matchName"))) {
            queryWrapper.eq("match_name", params.get("matchName").toString());
        }
        if(ObjectUtils.isNotEmpty(params.get("matchCode"))) {
            queryWrapper.eq("match_code", params.get("matchCode").toString());
        }
        if(ObjectUtils.isNotEmpty(params.get("day"))) {
            queryWrapper.eq("DATE_FORMAT( discharge_time, '%Y-%m-%d' )", params.get("day").toString());
        }
        if(ObjectUtils.isNotEmpty(params.get(ZhjdDataFilter.DATA_FILTER_SQL))) {
            queryWrapper.apply(params.get(ZhjdDataFilter.DATA_FILTER_SQL).toString());
        }
        queryWrapper.orderByDesc("discharge_time");
        queryWrapper.last(" limit 1 ");
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    @ZhjdDataFilter(tableAlias = "t1")
    public List<String> getProduceTime(Map<String, Object> params) {
        // 时间类型（年、月、日），默认为年
        if(ObjectUtils.isEmpty(params.get("timeType"))) {
            params.put("timeType", "year");
        }

        // 获取符合条件的数据
        return baseMapper.getProduceTime(params);
    }

    /**
     * 沥青主表数据存储
     */
    @Autowired
    private AsphaltDataWeightService asphaltDataWeightService;
    @Autowired
    private NAsphaltDataConfigService nAsphaltDataConfigService;
    @Override
    public Long saveDataBaseUpload(JSONObject json) {
        if("配给值".equals(json.getString("dataType"))){
            //----------主表数据存储----------
            AsphaltDataEntity entity = new AsphaltDataEntity();
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            //主键
            entity.setId(id);
            //拌合站主键
            entity.setStationCode(json.getString("type"));
            //配合比设定值
            //--
            //沥青温度
            entity.setAsphaltTemperature(isBigDecimal(json.getString("temperature")));
            //盘重
            entity.setBatchWeight(isBigDecimal(json.getString("outPut")));
            //入库时间
            entity.setInsertTime(new Date());
            if("KLLQLQ01".equals(json.getString("type"))){
                Date date = json.getDate("lTime");
                entity.setDischargeTime(DateUtils.addHours(date, -8));
            }else{
                entity.setDischargeTime(json.getDate("lTime"));
            }
            entity.setOriginalId(json.getString("id"));
            entity.setBatch(isInteger(json.getString("batch")));
            //取最新的数据记录
//            AsphaltDataEntity lastEntity = getLatestAsphaltData(json.getString("type"));
//            if(lastEntity!=null){
//                Integer lastBatch = lastEntity.getBatch();
//                Integer nowBatch = isInteger(json.getString("batch"));
//                Date nowDischargeTime = entity.getDischargeTime();
//                Date lastDischargeTime = lastEntity.getDischargeTime();
//                //若批次相邻，则计算出料时间差值
//                if(nowBatch!=null&&lastBatch!=null&&nowBatch-lastBatch==1&&nowDischargeTime!=null&&lastDischargeTime!=null){
//                    //计算两者相差秒
//                    Long diff = (nowDischargeTime.getTime()-lastDischargeTime.getTime())/1000;
//                    entity.setMixingDuration(diff.intValue());
//                }
//            }
            // 获取设定值数据
            NAsphaltDataConfigEntity configEntity = getLatestConfigData(json.getString("type"));
            if(configEntity!=null){
                entity.setMatchName(configEntity.getDataType());
            }
            //保存主表数据
            save(entity);
            //----------沥青重量详情数据----------
            AsphaltDataWeightEntity weightEntity = new AsphaltDataWeightEntity();
            weightEntity.setId(id);
            //沥青
            weightEntity.setAsphaltAct(isBigDecimal(json.getString("pitch")));
            //骨料
            weightEntity.setGravel1Act(isBigDecimal(json.getString("sand1")));
            weightEntity.setGravel2Act(isBigDecimal(json.getString("sand2")));
            weightEntity.setGravel3Act(isBigDecimal(json.getString("sand3")));
            weightEntity.setGravel4Act(isBigDecimal(json.getString("sand4")));
            weightEntity.setGravel5Act(isBigDecimal(json.getString("sand5")));
            weightEntity.setGravel6Act(isBigDecimal(json.getString("sand6")));
            //粉料
            weightEntity.setPowder1Act(isBigDecimal(json.getString("powder1")));
            weightEntity.setPowder2Act(isBigDecimal(json.getString("powder2")));

            // 沥青理论用量
            weightEntity.setAsphaltTheo(getLlValue(configEntity.getAsphaltTheo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            // 骨料1理论用量
            weightEntity.setGravel1Theo(getLlValue(configEntity.getGravel1Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setGravel2Theo(getLlValue(configEntity.getGravel2Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setGravel3Theo(getLlValue(configEntity.getGravel3Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setGravel4Theo(getLlValue(configEntity.getGravel4Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setGravel5Theo(getLlValue(configEntity.getGravel5Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setGravel6Theo(getLlValue(configEntity.getGravel6Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setPowder1Theo(getLlValue(configEntity.getPowder1Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setPowder2Theo(getLlValue(configEntity.getPowder2Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setPowder3Theo(getLlValue(configEntity.getPowder3Theo(),configEntity.getOutPut(),entity.getBatchWeight(),weightEntity.getAsphaltAct()));
            weightEntity.setConfigId(configEntity.getId());
            asphaltDataWeightService.save(weightEntity);
            try{
                asphaltDataSend(entity.getId());
            } catch (Exception e){
                e.printStackTrace();
            }
        }else{
            //若数据类型为设定值，则进行配比录入
            NAsphaltDataConfigEntity configEntity = new NAsphaltDataConfigEntity();
            configEntity.setFssj(json.getDate("lTime"));
            configEntity.setSourceId(json.getLong("id"));
            configEntity.setSource(json.getString("type"));
            configEntity.setOutPut(isBigDecimal(json.getString("outPut")));
            configEntity.setAsphaltTheo(isBigDecimal(json.getString("pitch")));
            configEntity.setGravel1Theo(isBigDecimal(json.getString("sand1")));
            configEntity.setGravel2Theo(isBigDecimal(json.getString("sand2")));
            configEntity.setGravel3Theo(isBigDecimal(json.getString("sand3")));
            configEntity.setGravel4Theo(isBigDecimal(json.getString("sand4")));
            configEntity.setGravel5Theo(isBigDecimal(json.getString("sand5")));
            configEntity.setPowder1Theo(isBigDecimal(json.getString("powder1")));
            configEntity.setPowder2Theo(isBigDecimal(json.getString("powder2")));
            configEntity.setCreateTime(new Date());
            configEntity.setDataType(json.getString("dataType"));
            nAsphaltDataConfigService.saveData(configEntity);
        }

        return json.getLong("id");
    }

    private void asphaltDataSend(String id) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("http://111.14.222.59:9163/prod-api/zhgd/asphaltData/isQualified?id="+id);
        CloseableHttpResponse response = httpClient.execute(httpGet);
        int status = response.getStatusLine().getStatusCode();
        if (status >= 200 && status < 300) {
            // 对得到后的实例可以进行处理，例如读取回复体，读取html
            HttpEntity entity = response.getEntity();
            System.out.println(new Date());
            System.out.println("=======================");
            String html = EntityUtils.toString(entity);
            System.out.println(html);
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
        // 6. 释放连接
        response.close();
        httpClient.close();
    }

    /**
     * 徐工集团版本沥青拌合站数据接收接口
     * @param json
     * @return
     */
    @Override
    public Long saveDataBaseUploadXg(JSONObject json) {
        //----------主表数据存储----------
        AsphaltDataEntity entity = new AsphaltDataEntity();
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        //主键
        entity.setId(id);
        //拌合站主键
        entity.setStationCode(json.getString("type"));
        entity.setOriginalId(json.getString("id"));
        //沥青温度
        entity.setAsphaltTemperature(isBigDecimal(json.getString("temperature")));
        //盘重
        entity.setBatchWeight(isBigDecimal(json.getString("outPut")));
        //入库时间
        entity.setInsertTime(new Date());
        entity.setDischargeTime(json.getDate("lTime"));
        entity.setOriginalId(json.getString("id"));
        entity.setBatch(isInteger(json.getString("batch")));
        entity.setMatchName(json.getString("match"));
        //保存主表数据
        save(entity);
        //----------沥青重量详情数据----------
        AsphaltDataWeightEntity weightEntity = new AsphaltDataWeightEntity();
        weightEntity.setId(id);
        //沥青
        weightEntity.setAsphaltAct(isBigDecimal(json.getString("pitch")));
        //骨料
        weightEntity.setGravel1Act(isBigDecimal(json.getString("sand1")));
        weightEntity.setGravel2Act(isBigDecimal(json.getString("sand2")));
        weightEntity.setGravel3Act(isBigDecimal(json.getString("sand3")));
        weightEntity.setGravel4Act(isBigDecimal(json.getString("sand4")));
        weightEntity.setGravel5Act(isBigDecimal(json.getString("sand5")));
        weightEntity.setGravel6Act(isBigDecimal(json.getString("sand6")));
        //粉料
        weightEntity.setPowder1Act(isBigDecimal(json.getString("powder1")));
        weightEntity.setPowder2Act(isBigDecimal(json.getString("powder2")));
        //-------------设定值---------------
        weightEntity.setAsphaltTheo(isBigDecimal(json.getString("pitchTheory")));
        weightEntity.setGravel1Theo(isBigDecimal(json.getString("sand1Theory")));
        weightEntity.setGravel2Theo(isBigDecimal(json.getString("sand2Theory")));
        weightEntity.setGravel3Theo(isBigDecimal(json.getString("sand3Theory")));
        weightEntity.setGravel4Theo(isBigDecimal(json.getString("sand4Theory")));
        weightEntity.setGravel5Theo(isBigDecimal(json.getString("sand5Theory")));
        weightEntity.setGravel6Theo(isBigDecimal(json.getString("sand6Theory")));
        weightEntity.setPowder1Theo(isBigDecimal(json.getString("powder1Theory")));
        weightEntity.setPowder2Theo(isBigDecimal(json.getString("powder2Theory")));
        asphaltDataWeightService.save(weightEntity);
        return json.getLong("id");
    }

    /**
     * 徐工集团版本沥青拌合站数据接收接口三标
     * @param json
     * @return
     */
    @Override
    public Long saveDataBaseUploadXgsb(JSONObject json) {
        //----------主表数据存储----------
        AsphaltDataEntity entity = new AsphaltDataEntity();
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        //主键
        entity.setId(id);
        //拌合站主键
        entity.setStationCode(json.getString("type"));
        entity.setOriginalId(json.getString("id"));
        //沥青温度
        entity.setAsphaltTemperature(isBigDecimal(json.getString("temperature")));
        //盘重
        entity.setBatchWeight(isBigDecimal(json.getString("outPut")));
        //入库时间
        entity.setInsertTime(new Date());
        entity.setDischargeTime(json.getDate("lTime"));
        entity.setBatch(isInteger(json.getString("batch")));
        entity.setMatchName(json.getString("match"));
        //保存主表数据
        save(entity);
        //----------沥青重量详情数据----------
        AsphaltDataWeightEntity weightEntity = new AsphaltDataWeightEntity();
        weightEntity.setId(id);
        //沥青
        weightEntity.setAsphaltAct(isBigDecimal(json.getString("pitch")));
        //骨料
        weightEntity.setGravel1Act(isBigDecimal(json.getString("sand1")));
        weightEntity.setGravel2Act(isBigDecimal(json.getString("sand2")));
        weightEntity.setGravel3Act(isBigDecimal(json.getString("sand3")));
        weightEntity.setGravel4Act(isBigDecimal(json.getString("sand4")));
        weightEntity.setGravel5Act(isBigDecimal(json.getString("sand5")));
        weightEntity.setGravel6Act(isBigDecimal(json.getString("sand6")));
        //粉料
        weightEntity.setPowder1Act(isBigDecimal(json.getString("powder1")));
        weightEntity.setPowder2Act(isBigDecimal(json.getString("powder2")));
        //-------------设定值---------------
        weightEntity.setAsphaltTheo(isBigDecimal(json.getString("pitchTheory")));
        weightEntity.setGravel1Theo(isBigDecimal(json.getString("sand1Theory")));
        weightEntity.setGravel2Theo(isBigDecimal(json.getString("sand2Theory")));
        weightEntity.setGravel3Theo(isBigDecimal(json.getString("sand3Theory")));
        weightEntity.setGravel4Theo(isBigDecimal(json.getString("sand4Theory")));
        weightEntity.setGravel5Theo(isBigDecimal(json.getString("sand5Theory")));
        weightEntity.setGravel6Theo(isBigDecimal(json.getString("sand6Theory")));
        weightEntity.setPowder1Theo(isBigDecimal(json.getString("powder1Theory")));
        weightEntity.setPowder2Theo(isBigDecimal(json.getString("powder2Theory")));
        asphaltDataWeightService.save(weightEntity);
        return json.getLong("id");
    }

    /**
     * 玛连尼sqlserver-济微四标沥青拌合站
     * @param json
     * @return
     */
    @Override
    @Transactional
    public Long saveDataBaseUploadMln(JSONObject json) {

        //----------主表数据存储----------
        AsphaltDataEntity entity = new AsphaltDataEntity();
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        //主键
        entity.setId(id);
        //拌合站主键
        entity.setStationCode(json.getString("type"));
        entity.setOriginalId(json.getString("id"));
        //沥青温度（成品料温）
        entity.setAsphaltTemperature(isBigDecimal(json.getString("temperature")));
        // 溜槽温度
        entity.setSluiceTemperature(isBigDecimal(json.getString("finishTemperature")));
        //入库时间
        entity.setInsertTime(new Date());
        entity.setDischargeTime(json.getDate("lTime"));
        entity.setOriginalId(json.getString("id"));
        entity.setBatch(isInteger(json.getString("batch")));
        entity.setMatchName(json.getString("match"));
        //配方Id（code）
        entity.setMatchCode(json.getString("recipeId"));
        //骨料温度，
        entity.setGlTemperature(isBigDecimal(json.getString("glTemperature")));
        //沥青温度
        entity.setLqTemperature(isBigDecimal(json.getString("lqTemperature")));
        //----------沥青重量详情数据----------
        AsphaltDataWeightEntity weightEntity = new AsphaltDataWeightEntity();
        weightEntity.setId(id);
        //沥青
        weightEntity.setAsphaltAct(isBigDecimal(json.getString("pitch")));
        //骨料
        weightEntity.setGravel1Act(isBigDecimal(json.getString("sand1")));
        weightEntity.setGravel2Act(isBigDecimal(json.getString("sand2")));
        weightEntity.setGravel3Act(isBigDecimal(json.getString("sand3")));
        weightEntity.setGravel4Act(isBigDecimal(json.getString("sand4")));
        weightEntity.setGravel5Act(isBigDecimal(json.getString("sand5")));
        weightEntity.setGravel6Act(isBigDecimal(json.getString("sand6")));
        //粉料
        weightEntity.setPowder1Act(isBigDecimal(json.getString("powder1")));
        weightEntity.setPowder2Act(isBigDecimal(json.getString("powder2")));
        BigDecimal batchWeight = weightEntity.getAsphaltAct()==null?BigDecimal.ZERO:weightEntity.getAsphaltAct();
        batchWeight =
                batchWeight.add(weightEntity.getGravel1Act()==null?BigDecimal.ZERO:weightEntity.getGravel1Act())
                .add(weightEntity.getGravel2Act()==null?BigDecimal.ZERO:weightEntity.getGravel2Act())
                .add(weightEntity.getGravel3Act()==null?BigDecimal.ZERO:weightEntity.getGravel3Act())
                .add(weightEntity.getGravel4Act()==null?BigDecimal.ZERO:weightEntity.getGravel4Act())
                .add(weightEntity.getGravel5Act()==null?BigDecimal.ZERO:weightEntity.getGravel5Act())
                .add(weightEntity.getGravel6Act()==null?BigDecimal.ZERO:weightEntity.getGravel6Act())
                .add(weightEntity.getPowder1Act()==null?BigDecimal.ZERO:weightEntity.getPowder1Act())
                .add(weightEntity.getPowder2Act()==null?BigDecimal.ZERO:weightEntity.getPowder2Act());
        //计算总盘重
        entity.setBatchWeight(batchWeight);
        //骨料+粉料的总重量
        BigDecimal gfWeight = batchWeight.subtract(weightEntity.getAsphaltAct()==null?BigDecimal.ZERO:weightEntity.getAsphaltAct());
        //保存主表数据
        save(entity);

        //-------------设定值---------------
        weightEntity.setAsphaltTheo(isBigDecimal(json.getString("pitchTheory")));
        weightEntity.setGravel1Theo(isBigDecimal(json.getString("sand1Theory")));
        weightEntity.setGravel2Theo(isBigDecimal(json.getString("sand2Theory")));
        weightEntity.setGravel3Theo(isBigDecimal(json.getString("sand3Theory")));
        weightEntity.setGravel4Theo(isBigDecimal(json.getString("sand4Theory")));
        weightEntity.setGravel5Theo(isBigDecimal(json.getString("sand5Theory")));
        weightEntity.setGravel6Theo(isBigDecimal(json.getString("sand6Theory")));
        weightEntity.setPowder1Theo(isBigDecimal(json.getString("powder1Theory")));
        weightEntity.setPowder2Theo(isBigDecimal(json.getString("powder2Theory")));
        asphaltDataWeightService.save(weightEntity);
        return json.getLong("id");

    }

    /**
     * 济微一标沥青数据采集/济微四标沥青
     * @param json
     * @return
     */
    @Override
    @Transactional
    public Long saveDataBaseUploadYb(JSONObject json) {
        //----------主表数据存储----------
        AsphaltDataEntity entity = new AsphaltDataEntity();
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        //主键
        entity.setId(id);
        //拌合站主键
        entity.setStationCode(json.getString("type"));
        entity.setOriginalId(json.getString("id"));
        //沥青温度
        entity.setAsphaltTemperature(isBigDecimal(json.getString("temperature")));
        // 溜槽温度
        entity.setSluiceTemperature(isBigDecimal(json.getString("finishTemperature")));
        //入库时间
        entity.setInsertTime(new Date());
        entity.setDischargeTime(json.getDate("lTime"));
        entity.setOriginalId(json.getString("id"));
        entity.setBatch(isInteger(json.getString("batch")));
        entity.setMatchName(json.getString("match"));
        //----------沥青重量详情数据----------
        AsphaltDataWeightEntity weightEntity = new AsphaltDataWeightEntity();
        weightEntity.setId(id);
        //沥青
        weightEntity.setAsphaltAct(isBigDecimal(json.getString("pitch")));
        //骨料
        weightEntity.setGravel1Act(isBigDecimal(json.getString("sand1")));
        weightEntity.setGravel2Act(isBigDecimal(json.getString("sand2")));
        weightEntity.setGravel3Act(isBigDecimal(json.getString("sand3")));
        weightEntity.setGravel4Act(isBigDecimal(json.getString("sand4")));
        weightEntity.setGravel5Act(isBigDecimal(json.getString("sand5")));
        weightEntity.setGravel6Act(isBigDecimal(json.getString("sand6")));
        //粉料
        weightEntity.setPowder1Act(isBigDecimal(json.getString("powder1")));
        weightEntity.setPowder2Act(isBigDecimal(json.getString("powder2")));
        BigDecimal batchWeight = weightEntity.getAsphaltAct()
                .add(weightEntity.getGravel1Act()).add(weightEntity.getGravel2Act()).add(weightEntity.getGravel3Act())
                        .add(weightEntity.getGravel4Act()).add(weightEntity.getGravel5Act()).add(weightEntity.getGravel6Act())
                        .add(weightEntity.getPowder1Act()).add(weightEntity.getPowder2Act());
        //计算总盘重
        entity.setBatchWeight(batchWeight);
        //骨料+粉料的总重量
        BigDecimal gfWeight = batchWeight.subtract(weightEntity.getAsphaltAct());
        //保存主表数据
        save(entity);

        //-------------设定值---------------
        weightEntity.setAsphaltTheo(getLlValueYb(gfWeight,isBigDecimal(json.getString("pitchTheory"))));
        weightEntity.setGravel1Theo(getLlValueYb(gfWeight,isBigDecimal(json.getString("sand1Theory"))));
        weightEntity.setGravel2Theo(getLlValueYb(gfWeight,isBigDecimal(json.getString("sand2Theory"))));
        weightEntity.setGravel3Theo(getLlValueYb(gfWeight,isBigDecimal(json.getString("sand3Theory"))));
        weightEntity.setGravel4Theo(getLlValueYb(gfWeight,isBigDecimal(json.getString("sand4Theory"))));
        weightEntity.setGravel5Theo(getLlValueYb(gfWeight,isBigDecimal(json.getString("sand5Theory"))));
        weightEntity.setGravel6Theo(getLlValueYb(gfWeight,isBigDecimal(json.getString("sand6Theory"))));
        weightEntity.setPowder1Theo(getLlValueYb(gfWeight,isBigDecimal(json.getString("powder1Theory"))));
        weightEntity.setPowder2Theo(getLlValueYb(gfWeight,isBigDecimal(json.getString("powder2Theory"))));
        asphaltDataWeightService.save(weightEntity);
        return json.getLong("id");
    }

    private BigDecimal getLlValueYb(BigDecimal gfWeight, BigDecimal llValue) {
        if (gfWeight != null && llValue != null) {
            return gfWeight.multiply(llValue.multiply(BigDecimal.valueOf(0.01)));
        }
        return null;
    }
    private AsphaltDataEntity getLatestAsphaltData(String source) {
        QueryWrapper<AsphaltDataEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("station_code", source);
        queryWrapper.orderByDesc("original_id");
        queryWrapper.last("LIMIT 1");
        return getOne(queryWrapper);
    }

    /**
     * 获取理论用量
     * @param gravel1Theo 设定值
     * @param outPutLl    理论总重量
     * @param outPutSj  实际总重量
     * @param asphaltAct  沥青实际用量
     * @return 理论用量
     */
    private BigDecimal getLlValue(BigDecimal gravel1Theo, BigDecimal outPutLl,BigDecimal outPutSj,BigDecimal asphaltAct) {
        // 参数验证
        if (gravel1Theo == null || outPutLl == null || outPutSj == null || asphaltAct == null) {
            return  null;
        }
        if (outPutLl.compareTo(BigDecimal.ZERO) == 0) {
            return  null;
        }
        // 实际总重量-沥青实际用量 与 理论总重量之比
        BigDecimal b = (outPutSj.subtract(asphaltAct)).divide(outPutLl, 4, BigDecimal.ROUND_HALF_UP);
        // 设定值乘以比值
        return gravel1Theo.multiply(b);
    }

    /**
     * 获取拌合站最后一次设定值状态
     * @param source
     * @return
     */
    private NAsphaltDataConfigEntity getLatestConfigData(String source) {
        QueryWrapper<NAsphaltDataConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("source", source);
        queryWrapper.orderByDesc("id");
        queryWrapper.last("LIMIT 1");
        return nAsphaltDataConfigService.getOne(queryWrapper);
    }

    private BigDecimal isBigDecimal(String str) {
        if(str == null || str.equals("")) {
            return null;
        }
        str = str.trim();
        if(str.matches("^[0-9]+.?[0-9]*$")) {
            return new BigDecimal(str);
        }else{
            return null;
        }
    }
    private Integer isInteger(String str) {
        if(str == null || str.equals("")) {
            return null;
        }
        if(str.matches("^[0-9]+.?[0-9]*$")) {
            return Integer.parseInt(str);
        }else{
            return null;
        }
    }
}
